function gameeditor(){
    this.collection;
    this.currentShape;
    this.currentEditedPoints = [];
    this.editShape;
    this.tokens = [];
}
gameeditor.prototype.getUUID = function(){
    var d = new Date().getTime();
    var pathern = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
    var uuid = pathern.replace(/[xy]/g, function(c) {
        var r = (d + Math.random()*16)%16 | 0;
        d = Math.floor(d/16);
        return (c=='x' ? r : (r&0x3|0x8)).toString(16);
    });
    return uuid;
}
gameeditor.prototype.generateTokenID = function(){
    var token = game.gameEditor.getUUID();
    if($.inArray(token,game.gameEditor.tokens) != -1)
        return game.gameEditor.generateTokenID();
    else {
        game.gameEditor.tokens.push(token);
        return token
    }
}
gameeditor.prototype.newCollection = function(name){
    game.gameEditor.collection = {
        name: name,
        shapes: {}
    }
}
gameeditor.prototype.openImport = function(json){

}
gameeditor.prototype.openSave = function(json){
    //On clos la modal
    $("#jqueryWindow").dialog("close");
    // D'abord on ajoute les tokens
    for(var i in json.tokens)
        game.gameEditor.tokens.push(json.tokens[i]);
    // On crée la collection
    var html = $("#htmlPathern #collection").html();
    html = html.replace('%name%',json.collection.name);
    $("#editorLayers #projectLayers").html(html);
    game.gameEditor.newCollection(json.collection.name);
    // On ajoute les shapes
    for(var i in json.collection.shapes) {
        var html = $("#htmlPathern #shape").html();
        html = html.replace('%name%',json.collection.shapes[i].name);
        html = html.replace(/%id%/g,i);
        $("#editorLayers #shapes").append(html);
        delete(html);
        game.gameEditor.collection.shapes[i] = json.collection.shapes[i];
        for(var j in o = ["N","E","S","W"]){
            var tokens = new Array;
            var group_count = 0;
            for(var token in json.collection.shapes[i][o[j]]){
                if($.inArray(token, tokens) == -1) {
                    tokens.push(token);
                    group_count++;
                    var group = $("#htmlPathern #group").html();
                    group = group.replace(/%id%/g, token);
                    group = group.replace('%position%', group_count);
                    group = group.replace('%color_line%', json.collection.shapes[i][o[j]][token].stroke);
                    group = group.replace('%color_fill%', json.collection.shapes[i][o[j]][token].fill);
                    $("#" + o[j] + "Layer_" + i + " div.shape ul:first-child").append(group);
                    delete(group);
                    for (var k in json.collection.shapes[i][o[j]][token].points) {
                        var instruction = $("#htmlPathern #instruction").html();
                        instruction = instruction.replace(/%id%/g, token);
                        instruction = instruction.replace("%pos%", k);
                        instruction = instruction.replace("%type%", json.collection.shapes[i][o[j]][token].points[k].type);
                        var coords = json.collection.shapes[i][o[j]][token].points[k].coords;
                        var props_text = "";
                        switch (json.collection.shapes[i][o[j]][token].points[k].type) {
                            case "line":
                                props_text = 'X:<span class="XProperty">' + coords.x + '</span> Y:<span class="YProperty">' + coords.y + '</span>';
                                break;
                            case "arc":
                                props_text = 'X:<span class="XProperty">' + coords.x + '</span> Y:<span class="YProperty">' + coords.y + '</span> R:<span class="RProperty">' + coords.r + '</span>';
                                break;
                            case "bezier":
                                props_text = 'X:<span class="XProperty">' + coords.x + '</span> Y:<span class="YProperty">' + coords.y + '</span> CX:<span class="CXProperty">' + coords.cx + '</span> CY:<span class="CYProperty">' + coords.cy + '</span>';
                                break;
                        }
                        instruction = instruction.replace("%properties%", props_text);
                        $("#group_" + token + "_instructions").append(instruction);
                        delete(instruction);
                    }
                }
            }
        }
        game.gameGui.addEvtUI(i);
    }
    if(!!$("#editorLayers #shapes").data("ui-accordion"))
        $("#editorLayers #shapes").accordion('destroy');
    $("#editorLayers #shapes").accordion({
        active: false,
        heightStyle: "fill",
        collapsible: true,
        header: ".shapeTitle"
    });
    $( "#editorLayers #shapes .shapeLayers" ).tabs();
}
gameeditor.prototype.save = function(name){

}
gameeditor.prototype.export = function(name){

}
gameeditor.prototype.addShape = function(name, format){
    var token = game.gameEditor.generateTokenID();
    game.gameEditor.collection.shapes[token] = {
        name: name,
        format: format,
        N: {},
        E: {},
        S: {},
        W: {}
    }
    return token;
}
gameeditor.prototype.removeShape = function(id){

}
gameeditor.prototype.openShape = function(id){

}
gameeditor.prototype.addGroup = function(id, position){
    var token = game.gameEditor.generateTokenID();
    game.gameEditor.collection.shapes[id][game.gameMap.currentOrientation][token] = {
        position:position,
        startPoint:{},
        points: [],
        fill:"",
        stroke:"",
        shape:undefined
    }
    return token;
}
gameeditor.prototype.removeGroup = function(id){

}
gameeditor.prototype.addPoints = function(id, group, args, type){
    game.gameEditor.collection.shapes[id][game.gameMap.currentOrientation][group].points.push({
        type: type,
        coords: args
    });
}
gameeditor.prototype.removePoint = function(group, id){

}
gameeditor.prototype.movePoint = function(group, id, coords){

}
gameeditor.prototype.cleanShape = function(){
    if(game.gameEditor.currentShape != undefined) {
        game.gameEditor.currentShape.removeAllEventListeners();
        game.mainContainer.removeChild(game.gameEditor.currentShape);
        delete(game.gameEditor.currentShape);
        game.gameMap.cleanInitTiles();
        game.gameMap.updateGrid();
    }
}
gameeditor.prototype.parseShape = function(id){
    game.gameEditor.currentShape = new createjs.Shape();
    game.gameEditor.currentShape.regX = 0;
    game.gameEditor.currentShape.regY = 0;
    game.gameEditor.currentShape.x = 0;
    game.gameEditor.currentShape.y = 0;
    game.gameEditor.currentShape.zIndex = 50;
    var groups = game.gameEditor.collection.shapes[id][game.gameGui.currentOrientation];
    var groupsOrdered = {};
    for(var token in groups){
        groupsOrdered[groups[token].position] = groups[token]
        groupsOrdered[groups[token].position][token] = token;
    }
    for(var id in groupsOrdered){
        if(groupsOrdered[id].fill != "")
            game.gameEditor.currentShape.graphics.beginFill(groupsOrdered[id].fill);
        if(groupsOrdered[id].stroke != "")
            game.gameEditor.currentShape.graphics.beginStroke(groupsOrdered[id].stroke);
        game.gameEditor.currentShape.graphics.moveTo(groupsOrdered[id].startPoint.x,groupsOrdered[id].startPoint.y);
        var previous;
        for(var i in groupsOrdered[id].points){
            switch(groupsOrdered[id].points[i].type){
                case "line":
                    game.gameEditor.currentShape.graphics.lineTo(groupsOrdered[id].points[i].coords.x, groupsOrdered[id].points[i].coords.y);
                    break;
                case "arc":
                    game.gameEditor.currentShape.graphics.arcTo(groupsOrdered[id].points[i].coords.cx, groupsOrdered[id].points[i].coords.cy, groupsOrdered[id].points[i].coords.x, groupsOrdered[id].points[i].coords.y, groupsOrdered[id].points[i].coords.r)
                    break;
                case "bezier":
                    game.gameEditor.currentShape.graphics.quadraticCurveTo(groupsOrdered[id].points[i].coords.cx, groupsOrdered[id].points[i].coords.cy, groupsOrdered[id].points[i].coords.x, groupsOrdered[id].points[i].coords.y);
                    break;
            }
            previous = groupsOrdered[id].points[i].coords;
        }
        if(groupsOrdered[id].fill != "")
            game.gameEditor.currentShape.graphics.endFill();
        if(groupsOrdered[id].stroke != "")
            game.gameEditor.currentShape.graphics.endStroke();
    }
    game.mainContainer.addChild(game.gameEditor.currentShape);
}
gameeditor.prototype.displayEditPoints = function(){
    game.gameEditor.currentEditedPoints = [];
    var group = game.gameEditor.collection.shapes[game.gameGui.currentShapeID][game.gameGui.currentOrientation][game.gameGui.currentGroupID];
    game.gameEditor.currentEditedPoints.push({
        type:"startPoint",
        coords: group["startPoint"]
    })
    for(var i in group.points) {
        game.gameEditor.currentEditedPoints.push({
            type: group.points[i].type,
            coords: group.points[i].coords
        })
    }
    game.gameEditor.drawEditorGuides();
}
gameeditor.prototype.drawEditorGuides = function(){
    if(game.gameEditor.editShape != undefined){
        game.mainContainer.removeChild(game.gameEditor.editShape);
    }

    if(game.gameEditor.currentEditedPoints.length > 0) {
        game.gameEditor.editShape = new createjs.Shape();
        game.gameEditor.editShape.x = 0;
        game.gameEditor.editShape.y = 0;
        game.gameEditor.editShape.regX = 0;
        game.gameEditor.editShape.regY = 0;
        game.gameEditor.editShape.zIndex = 200;

        var prevPoint = {};
        for (var i in game.gameEditor.currentEditedPoints) {
            switch(game.gameEditor.currentEditedPoints[i].type){
                case "startPoint":
                    game.gameEditor.editShape.graphics
                        .beginStroke("#ff0000")
                        .setStrokeStyle(0.5)
                        .moveTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x + 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x + 1, game.gameEditor.currentEditedPoints[i].coords.y + 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y + 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .endStroke()
                        .beginFill("#ff0000")
                        .drawCircle(game.gameEditor.currentEditedPoints[i].coords.x, game.gameEditor.currentEditedPoints[i].coords.y, 0.5)
                        .endFill();
                    break;
                case "line":
                    game.gameEditor.editShape.graphics
                        .beginStroke("#ff0000")
                        .setStrokeStyle(0.5)
                        .moveTo(prevPoint.x, prevPoint.y)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x, game.gameEditor.currentEditedPoints[i].coords.y)
                        .moveTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x + 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x + 1, game.gameEditor.currentEditedPoints[i].coords.y + 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y + 1)
                        .lineTo(game.gameEditor.currentEditedPoints[i].coords.x - 1, game.gameEditor.currentEditedPoints[i].coords.y - 1)
                        .endStroke()
                        .beginFill("#ff0000")
                        .drawCircle(game.gameEditor.currentEditedPoints[i].coords.x, game.gameEditor.currentEditedPoints[i].coords.y, 0.5)
                        .endFill();
                    break;
                case "arc":

                    break;
                case "bezier":

                    break;
            }
            prevPoint = {
                x: game.gameEditor.currentEditedPoints[i].coords.x,
                y: game.gameEditor.currentEditedPoints[i].coords.y
            };
        }

        game.mainContainer.addChild(game.gameEditor.editShape);
    }
}
gameeditor.prototype.refreshShape = function(id){
    game.gameEditor.cleanShape();
    game.gameEditor.parseShape(game.gameGui.currentShapeID);
    game.gameEditor.drawEditorGuides();
}